package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.constants.RedisConstants;
import com.tianji.remark.domain.dto.LikeRecordFormDTO;
import com.tianji.remark.domain.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.StringRedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author WangXinyi
 * @since 2025-01-03
 */
@Service
@RequiredArgsConstructor
public class RedisLikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RabbitMqHelper mqHelper;

    /**
     * 点赞或取消赞
     * set: key:biz_id value:user_id
     * zset: key:biz_type value:biz_id score: num(点赞数量)
     *
     * @param dto
     */
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public void addLikeRecord(LikeRecordFormDTO dto) {
        Long userId = UserContext.getUser();
        String key = RedisConstants.LIKED_RECORDS + dto.getBizId();
        String value = userId.toString();
        Long result = 0L;
        //1.判断是否点赞过
        if (dto.getLiked()) {
            //点赞
            //查询是否点赞过
            result = redisTemplate.opsForSet().add(key, value);
            if (result == null || result == 0) {
                //已经点过赞，或者redis出故障
                return;
            }
            //统计点赞个数
            Long size = redisTemplate.opsForSet().size(key);
            if (size == null) {
                return;
            }
            //存放到zset中
            key = RedisConstants.LIKED_TIMES + dto.getBizType();
            value = dto.getBizId().toString();
            redisTemplate.opsForZSet().add(key, value, size.doubleValue()); //已有数据会累加

        } else {
            //取消点赞
            result = redisTemplate.opsForSet().remove(key, value);
            if (result == null || result == 0) {
                //取消点赞失败，或者redis出故障
                return;
            }
        }
    }


    /**
     * 查询指定业务id的点赞状态
     */
    @Override
    public Set<Long> isBizLiked(List<Long> bizIds) {
        // 1.获取登录用户id
        Long userId = UserContext.getUser();
        // 2.查询点赞状态
        List<Object> objects = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
            StringRedisConnection src = (StringRedisConnection) connection;
            for (Long bizId : bizIds) {
                String key = RedisConstants.LIKED_RECORDS + bizId;
                src.sIsMember(key, userId.toString());
            }
            return null;
        });
        // 3.返回结果
        return IntStream.range(0, objects.size()) // 创建从0到集合size的流
                .filter(i -> (boolean) objects.get(i)) // 遍历每个元素，保留结果为true的角标i
                .mapToObj(bizIds::get)// 用角标i取bizIds中的对应数据，就是点赞过的id
                .collect(Collectors.toSet());// 收集
    }
}